package com.qianya.weishi_server.config.security;


import com.qianya.weishi_server.config.jwt.JwtProperty;
import com.qianya.weishi_server.config.jwt.JwtUtil;
import com.qianya.weishi_server.common.result.GenericErrorCode;
import com.qianya.weishi_server.common.exception.GenericException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @author LLL
 */
@Slf4j
public class SecurityProviderManager {
    private static final String TOKEN_HEADER_NAME = "Authorization";

    private JwtProperty jwtProperty;

    SecurityProviderManager(JwtProperty jwtProperty) {
        this.jwtProperty = jwtProperty;
    }

    private String resolveToken(HttpServletRequest request) {
        String token = request.getHeader(TOKEN_HEADER_NAME);
        if (StringUtils.isBlank(token)) {
            throw new GenericException(GenericErrorCode.NO_TOKEN_ERROR);
        }
        return token;
    }

    Authentication parseToken(HttpServletRequest request) {
        String token = this.resolveToken(request);
        token = token.replace("Bearer ", "");

        Claims claims;
        try {
            claims = JwtUtil.parseToken(token, jwtProperty);
        } catch (ExpiredJwtException e1) {
//            throw new GenericException(GenericErrorCode.TOKEN_TIMEOUT_ERROR);
            //TODO 测试时开启，屏蔽掉token过期时间
            claims = e1.getClaims();
        } catch (JwtException e2) {
            e2.printStackTrace();
            throw new GenericException(GenericErrorCode.TOKEN_VALID_ERROR);
        }
        return new StatelessTokenAuthentication(claims);
    }


    /*刷新token并解析返回*/
    public Authentication tryRefreshAndParseToken(HttpServletRequest request, HttpServletResponse response) {
        String token = this.resolveToken(request);
        token = token.replace("Bearer ", "");

        String refreshToken = JwtUtil.refreshToken(token, jwtProperty);

        Claims claims;
        try {
            claims = JwtUtil.parseToken(refreshToken, jwtProperty);
        } catch (Exception e2) {
            e2.printStackTrace();
            throw new GenericException(GenericErrorCode.TOKEN_VALID_ERROR);
        }

        response.addHeader("token", refreshToken);
        return new StatelessTokenAuthentication(claims);
    }

}
